from django.contrib.gis.db import models
from django.utils.translation import ugettext_lazy as _

import sys, os
#import ogr, osr # not currently being used
from datetime import datetime
#from duetopia.register.geo import extents_to_wgs84, as_wkt_poly

class Directory(models.Model):
    """ A target for local filesystem indexing = a directory.
    Used to build a list of places to look when auditing a filesystem for geodata.
    
    >>> c = Directory(path='/tmp/')
    """
    __module__ = 'duetopia.register.models'
    path = models.CharField(max_length=255, verbose_name=_('path'))
    last_visited = models.DateTimeField(null=True)
    last_modified = models.DateTimeField(null=True)
    index = models.BooleanField(null=True)
    recurse = models.BooleanField(null=True)

    class Admin:
        list_display = ('path', 'last_visited', 'last_modified')
    class Meta:
        verbose_name = _('directory')
        verbose_name_plural = _('directories')

    def __str__(self):
        return self.path

    def filenames(self):
        try:
            (base, dirs, files) = os.walk(self.path).next()
            self.visit(time=datetime.now())
            return files
        except StopIteration:
            return None

    def dirs(self):
        if self.recurse is False: return None
        try:
            (base, dirs, files) = os.walk(self.path).next()
            
            objects = []
            for d in dirs:
                (dir,status) = Directory.objects.get_or_create(path=self.path+d+'/')
                objects.append(dir)
                objects.append(dir.dirs())
            return objects
        except StopIteration:
            return None

    def search_for_geodata(self):
        filenames = self.filenames() 
        self.visit(time=datetime.now())
        if filenames is None: return [] 
        files = []
        for n in filenames:
            file = None
            try:
                file = File.objects.get(name=n,path=self)
            except:
                pass

            if file is None:    
                if self.is_this_geodata(str(self)+n) is True:
                    (file,status) = File.objects.get_or_create(name=n,path=self)

            # only save state on geographic objects 
                    file.save()
            if file is not None:
                print file.name
                files.append(file)
        return files

    def visit(self,time=None):
        self.last_visited = time
        self.save()

    def is_this_geodata(self,file=None):
        ext = file.split('.')[-1] 
        if ext in File._ignore_suffix:
            return False
        try:
            ds = ogr.Open(file)
            ds.Destroy()
            return True
        except ogr.OGRError:
            return False 


        
class File(models.Model):
    # components of data sets that ogr will falsely pick up
    _ignore_suffix = ['shx','dbf','qix','osm','zip']

    __module__ = 'duetopia.register.models'
    name = models.CharField(max_length=255, verbose_name=_('name'))
    path = models.ForeignKey(Directory, verbose_name=_('path'))
    last_visited = models.DateTimeField(auto_now_add=True, verbose_name=_('last visited'))
    last_modified = models.DateTimeField(null=True,blank=True, verbose_name=_('last modified'))

    class Admin:
        pass
    def __str__(self):
        return self.name

    def extension(self):
        extension = self.name.split('.')[-1]
        return extension

    def is_geodata(self):
        
        if hasattr(self,'_ds') is True: return True
        if hasattr(self,'path') is False: return False

        if self.extension() in File._ignore_suffix: return False

        try:
            ds = ogr.Open(str(self.path.path+self.name))
            self._ds = ds 
            self.visit(time=datetime.now())
            return True
        except ogr.OGRError:
            return False

    def format(self):
        if self.is_geodata() is False:
            return None
        return self._ds.GetDriver().GetName()

    def layers(self):
        if hasattr(self,'_layers') is True: return self._layers
        layers = []
        if self.is_geodata() is False:
            return None 
        for i in range(self._ds.GetLayerCount()):
            layers.append(self._ds.GetLayer(i))
        self._layers = layers
        return layers

    def extents(self):
        if self.is_geodata() is False:
            return None
        layer = self.layers()[0] 
        extents = extents_to_wgs84(layer.GetExtent(),ref=layer.GetSpatialRef())
        return extents 
        
    def keywords(self):
        """Different means to look for keywords with OGR"""
        layers = self.layers()
        if layers is None: return None
        keywords = []
        for l in layers:
            keywords.append(l.GetName())
        return keywords
         

    def modified(self):
        file = None
        try:
            file = open(str(self.path.path+self.name))
        except:
            return None
        s = os.stat(self.path)
        t = datetime.fromtimestamp(s[ST_MTIME])
        self.last_modified = t
        self.save()
        return t

    def visit(self,time=None):
        self.last_visited = time
        self.save()

